﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Oracle.ManagedDataAccess.Client;
using WMS.FC.Domain.DomainObject.System;
using WMS.FC.Domain.PersistenceObject.Business;
using WMS.FC.Domain.Repository;
using WMS.FC.Infrastructure.Common;

namespace WMS.FC.Infrastructure.Repository
{
    public class CellRepository : RepositoryBase, ICellRepository
    {
        protected readonly IOptions<WmsSettings> options;

        public CellRepository(WmsDbContext dbContext, IOptions<WmsSettings> options) : base(dbContext)
        {
            this.options = options;
        }

        public async Task<int> BindeFakeCell(string trayBarcode, int cellPosition, UserInfo userInfo)
        {
            await dbContext.Set<CellPO>().AddAsync(new CellPO()
            {
                Id = SnowflakeIdHelper.Instance.NextId(),
                WarehouseCode = options.Value.WarehouseCode,
                Barcode = options.Value.FakeCellBarcodePrefix + SnowflakeIdHelper.Instance.NextId().ToString(),
                MaterialCode = "FakeCell",
                TechnologyRouteCode = options.Value.EmptyTrayTechnologyRoute,
                TechnologyProcessCode = options.Value.EmptyTrayTechnologyProcess,
                OriginalNgCode = null,
                NgCode = null,
                IsRework = false,
                RankValue = null,
                ReworkCount = 0,
                CellPosition = cellPosition,
                TrayBarcode = trayBarcode,
                CreatedBy = userInfo.UserName,
                CreateDate = DateTime.Now,
                ModifyIp = userInfo.UserIp
            });

            return await dbContext.SaveChangesAsync();
        }

        public async Task<CellPO?> GetCellByBarcode(string cellBarcode)
        {
            return await dbContext.Set<CellPO>().AsNoTrackingWithIdentityResolution().FirstOrDefaultAsync(entity => entity.Barcode == cellBarcode);
        }

        public async Task<int> UnbindFakeCell(string trayBarcode, int cellPosition, UserInfo userInfo)
        {
            var entities = dbContext.Set<CellPO>();
            var cellPO = await entities.FirstOrDefaultAsync(entity => entity.TrayBarcode == trayBarcode && entity.CellPosition == cellPosition);
            if (cellPO == null)
            {
                return 1;
            }
            else
            {
                entities.Remove(cellPO);
                return await dbContext.SaveChangesAsync();
            }
        }

        public async Task<int> UnbindTray(string trayBarcode, UserInfo userInfo)
        {
            return await dbContext.Database.ExecuteSqlRawAsync(@"UPDATE B_CELL T
   SET T.TRAY_BARCODE  = NULL,
       T.CELL_POSITION = NULL,
       T.MODIFY_DATE   = :MODIFY_DATE,
       T.MODIFIED_BY   = :MODIFIED_BY,
       T.MODIFY_IP     = :MODIFY_IP
 WHERE T.TRAY_BARCODE = :TRAY_BARCODE", new List<OracleParameter>()
            {
                new OracleParameter("TRAY_BARCODE", trayBarcode),
                new OracleParameter("MODIFY_DATE", DateTime.Now),
                new OracleParameter("MODIFIED_BY", userInfo.UserName),
                new OracleParameter("MODIFY_IP", userInfo.UserIp)
            });
        }
    }
}
